<?php

/**
 * An abstract implimentation of Log_XML with DOM functionality.
 *
 * PHP version 5.
 *
 * @category Logging
 * @package  Log
 * @author   Michael Peter 'Vladimyr' Gower <designatevoid@gmail.com>
 * @license  http://www.apache.org/licenses/LICENSE-2.0  Apache License 2.0
 * @link     http://pear.php.net/pepr/pepr-proposal-show.php?id=487
 */

/**
 * Require the base class.
 */
require_once 'Log/XML.php';

/**
 * This is an abstract implementation of Log_XML.  It utilizes only basic
 * string writing functions and is designed with speed in mind by using
 * an XML External Entity as inspired by Log4j's XMLLayout.
 *
 * @category Logging
 * @package  Log
 * @author   Michael Peter Gower <designatevoid@gmail.com>
 * @license  http://www.apache.org/licenses/LICENSE-2.0  Apache License 2.0
 * @link     http://pear.php.net/pepr/pepr-proposal-show.php?id=487
 * @since    Log_XML 1.0
 */
abstract class Log_XML_String extends Log_XML
{
    public function __construct(
        $filename = Log_XML::DEFAULT_FILENAME,
        $ident    = '',
        $conf     = array(),
        $level    = PEAR_LOG_DEBUG
    ) {
        parent::__construct($filename, $ident, $conf, $level);
    }


    public function open()
    {
        // If opened, then nothing to do
        if ($this->_opened === true) {
            return true;
        }

            // Call the parent
        $ret = parent::open();
        if ($ret === false) {
            return false;
        }

            // Does direct file access

            // Determine whether the log file needs to be created.
        $creating = !file_exists($this->filename);


            // Init the file handle.

        if (!$creating && $this->append === true && filesize($this->filename) != 0) {
            // appending

            $this->fileHandle = fopen($this->filename, "a+b");
            if (!$this->fileHandle) {
                $this->_opened = false;
                return false;
            }
            $this->_openend = true;

        } else { // create
            $this->fileHandle = fopen($this->filename, "w+b");
            if (!$this->fileHandle) {
                $this->_opened = false;
                return false;
            }
            $this->_openend = true;

                // if we can't create or save the header, delete and return false
            if (!$this->createHeader() || !$this->flush()) {
                if (is_file($this->filename)) {
                    $closeReturn = $this->close();
                    if ($closeReturn) {
                        unlink($this->filename);
                    }
                }
                $this->_opened = false;
                return false;
            }
            chmod($this->filename, $this->mode);
        }
        return $this->_opened;
    }

    public function close()
    {
        if ($this->_opened == false) {
            // nothing to do
            return true;
        }
        $ret = parent::close();
        $ret = $ret && fclose($this->fileHandle);
            // If we didn't do everything successfully, flag as
            // still opened and therefore not done
        $this->_opened = $ret != true;
        return $ret;
    }

    protected $fileHandle = null;

}